package org.systemsbiology.bigquery.gae.dao;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.memcache.MemcacheService;
import org.systemsbiology.addama.commons.gae.dataaccess.MemcacheLoaderCallback;
import org.systemsbiology.addama.commons.gae.dataaccess.callbacks.PutEntityTransactionCallback;

import java.io.Serializable;
import java.util.Date;
import java.util.logging.Logger;

import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService;
import static com.google.appengine.api.datastore.KeyFactory.createKey;
import static com.google.appengine.api.memcache.Expiration.byDeltaSeconds;
import static com.google.appengine.api.memcache.MemcacheServiceFactory.getMemcacheService;
import static org.systemsbiology.addama.commons.gae.dataaccess.DatastoreServiceTemplate.inTransaction;
import static org.systemsbiology.addama.commons.gae.dataaccess.MemcacheServiceTemplate.loadIfNotExisting;

/**
 * @author hrovira
 */
public class Queries {
    private static final Logger log = Logger.getLogger(Queries.class.getName());

    private static final DatastoreService datastore = getDatastoreService();
    private static final MemcacheService memcache = getMemcacheService("queries");

    public static void saveQuery(String jobId, QueriesPayload payload) {
        Entity e = new Entity(createKey("queries", jobId));
        e.setProperty("tq", payload.getTq());
        e.setProperty("tableId", payload.getTableId());
        e.setProperty("payload", payload.getPayload());
        e.setProperty("submitted", new Date());

        inTransaction(datastore, new PutEntityTransactionCallback(e));
    }

    public static QueriesPayload getQuery(String jobId) throws Exception {
        return (QueriesPayload) loadIfNotExisting(memcache, jobId, new QueriesMemcacheLoaderCallback(), byDeltaSeconds(3600));
    }

    private static class QueriesMemcacheLoaderCallback implements MemcacheLoaderCallback {
        public Serializable getCacheableObject(String jobId) throws Exception {
            try {
                Entity e = datastore.get(createKey("queries", jobId));
                String tq = "";
                if (e.hasProperty("tq")) tq = e.getProperty("tq").toString();
                String tableId = "";
                if (e.hasProperty("tableId")) tableId = e.getProperty("tableId").toString();
                String payload = "";
                if (e.hasProperty("payload")) payload = e.getProperty("payload").toString();

                return new QueriesPayload(tq, tableId, payload);
            } catch (EntityNotFoundException ex) {
                log.warning(ex.getMessage());
            }
            return null;
        }
    }

}
